import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { FRIDAY_LLM_CONFIG } from './constants';
import {
  BaseMessagePromptTemplateLike,
  ChatPromptTemplate,
  MessagesPlaceholder,
} from '@langchain/core/prompts';
import { createOpenAIFunctionsAgent, AgentExecutor } from 'langchain/agents';
import { StructuredToolInterface } from '@langchain/core/tools';
import { TavilySearchResults } from '@langchain/community/tools/tavily_search';

import { createInterface } from 'readline';
// import { AIMessage, HumanMessage } from '@langchain/core/messages';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';

import { CheerioWebBaseLoader } from '@langchain/community/document_loaders/web/cheerio';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
// import { TavilySearch } from '@langchain/tavily';
import { createRetrieverTool } from 'langchain/tools/retriever';

export async function agent() {
  const model = new ChatOpenAI({
    verbose: true, // 控制台日志
    model: 'gpt-4.1',
    temperature: 0.9,
    configuration: {
      baseURL: FRIDAY_LLM_CONFIG.API_BASE_URL,
      apiKey: FRIDAY_LLM_CONFIG.API_KEY,
    },
    // maxTokens: 8000,
  });

  const prompt = ChatPromptTemplate.fromMessages([
    ['system', '有什么可以帮你的吗？'],
    new MessagesPlaceholder('chat_history'),
    ['human', '{input}'],
    new MessagesPlaceholder('agent_scratchpad'),
  ]);
  //https://app.tavily.com/home
  const searchTool = new TavilySearchResults({
    apiKey: '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',
  });

  const retriever = await createRetriever();
  const retrieverTool = createRetrieverTool(retriever, {
    name: 'npm_search_tool',
    description: '当搜索信息包含npm文字时，使用这个工具进行搜索',
  });
  const tools: StructuredToolInterface[] = [searchTool, retrieverTool];
  const agent = await createOpenAIFunctionsAgent({
    llm: model,
    prompt,
    tools,
  });

  //代理执行器
  const agentExecutor = new AgentExecutor({
    agent,
    tools,
  });

  // function askQuestion(question: string) {
  //   return agentExecutor.invoke({ input: question });
  // }
  const rl = createInterface({ input: process.stdin, output: process.stdout });

  const chat_history: BaseMessagePromptTemplateLike[] = [];
  const askQuestion = () => {
    rl.question('USER:', (question) => {
      agentExecutor
        .invoke({ input: question, chat_history })
        .then((res) => {
          console.log('AI:', res.output);
          chat_history.push(['human', question], ['ai', res.output]);
          // chat_history.push(
          //   new HumanMessage(question),
          //   new AIMessage(res.output),
          // );
          askQuestion();
        })
        .catch(console.error);
      // rl.close();
    });

    // rl.prompt();
  };
  askQuestion();
  // rl.question('AI:', (question) => {
  //   const response = agentExecutor.invoke({ input: question });
  //   console.log(response);
  //   // rl.close();
  // });
  // return await agentExecutor.invoke({ input: 'hello' });
}

async function createRetriever() {
  const loader = new CheerioWebBaseLoader(
    // b.url!,
    'https://baike.baidu.com/item/NPM/23807941',
  );
  const docs = await loader.load();
  //文档切片
  const splitter = new RecursiveCharacterTextSplitter({
    chunkSize: 200,
    chunkOverlap: 20,
  });
  // 文档切片
  const splitterDocs = await splitter.splitDocuments(docs);
  //向量
  const embeddings = new OpenAIEmbeddings({
    verbose: true, // 控制台日志
    model: 'text-embedding-3-large',
    configuration: {
      baseURL: FRIDAY_LLM_CONFIG.API_BASE_URL,
      apiKey: FRIDAY_LLM_CONFIG.API_KEY,
    },
  });
  // 向量存储
  const vectorStore = await MemoryVectorStore.fromDocuments(
    splitterDocs,
    embeddings,
  );

  const retriever = vectorStore.asRetriever({ k: 2 });
  return retriever;
}

// agent().catch(console.error);
